package org.gokeep.communication.engine.udp;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.MulticastSocket;
import java.nio.charset.Charset;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * @author xuning
 */
@Slf4j
public class UdpClientQueueLister implements Runnable {

    private LinkedBlockingQueue<DatagramPacket> messageQueue;

    private MulticastSocket multicastSocket;
    private DatagramSocket datagramSocket;

    private boolean run = true;

    /**
     * 实例化构建
     */
    public UdpClientQueueLister() {
        messageQueue = new LinkedBlockingQueue<>();
        try {
            multicastSocket = new MulticastSocket();
            datagramSocket = new DatagramSocket();
        } catch (IOException e) {
            log.warn("Init udp socket fail, cause: ", e);
        }
    }

    /**
     * 添加队列请求包
     *
     * @param datagramPacket
     */
    public void add(DatagramPacket datagramPacket) {
        this.messageQueue.add(datagramPacket);
    }

    /**
     * 停止服务
     */
    public void stop() {
        this.run = false;
    }

    /**
     * 从队列处理消息线程
     */
    @SneakyThrows
    @Override
    public void run() {
        if (messageQueue == null) {
            messageQueue = new LinkedBlockingQueue<>();
        }
        while (run) {
            try {
                DatagramPacket datagramPacket = this.messageQueue.take();
                if (datagramPacket.getAddress().isMulticastAddress()) {
                    multicastSocket.send(datagramPacket);
                } else {
                    datagramSocket.send(datagramPacket);
                }
                log.debug("Multicast socket send message: {}", new String(datagramPacket.getData(), Charset.defaultCharset()));
            } catch (IOException | InterruptedException e) {
                log.warn("Multicast socket send message fail, cause: ", e);
                Thread.currentThread().interrupt();
            }
        }
    }
}
